/*
 * Copyright 2013-2018 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.example.threadlocaltest.demos.web;

import com.google.gson.Gson;
import org.example.threadlocaltest.demos.configure.MyUserDetails;
import org.example.threadlocaltest.demos.configure.UnifiedReturn;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.sql.DataSource;
import java.util.Map;
import java.util.UUID;

@RestController
@RequestMapping("/public")
public class PublicController {

    @Autowired
    private DataSource dataSource;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping("/testDataSource")
    public UnifiedReturn<String> testDataSource() {
        return UnifiedReturn.success(dataSource.getClass().toString());
    }

    //login 该方法需要被放行
    @GetMapping("/login")
    public UnifiedReturn<String> login(@RequestParam("username") String username,
                                       @RequestParam("password") String password) {
        //认证
        UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authenticate = authenticationManager.authenticate(upToken);
        String json = new Gson().toJson(authenticate);

        System.out.println("json = " + json);
//        json = {"principal":{"username":"admin","password":"$2a$10$WQMloBfgYWA6eFQ/98WBB.Cj9T0NMDwi1FG9U1A0IQocpBBehlYqa",
//                "authorities":[{"role":"ROLE_ADMIN"}]},"authorities":[{"role":"ROLE_ADMIN"}],"authenticated":true}

        //一般来说，只要是 authenticate 不是 null 就代表认证成功了，然后就可以根据 某些信息生成 token 返回给前端,
        // 当然，还需要将 这个 token 和用户信息存储到 redis 中
        String token = UUID.randomUUID().toString();
        stringRedisTemplate.opsForValue().set(token, json);
        return UnifiedReturn.success(token);
    }


    //模拟一个 业务接口，用户获取他名下的所有订单信息
    @GetMapping("/getOrders")
    @PreAuthorize("hasAnyAuthority('ROLE_ADMIN')")//这个注解表示只有 ROLE_ADMIN 角色的用户才能访问这个接口
    public UnifiedReturn<String> getAllUser() {
        //在这里就能够通过 SecurityContextHolder 来获取到用户信息了
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        MyUserDetails principal = (MyUserDetails) authentication.getPrincipal();
        System.out.println("principal = " + principal);
//        principal = MyUserDetails(username=admin,
//                                  password=$2a$10$WQMloBfgYWA6eFQ/98WBB.Cj9T0NMDwi1FG9U1A0IQocpBBehlYqa,
//                                  authorities=[{role=ROLE_ADMIN}])
        return UnifiedReturn.success("成功用户获取他名下的所有订单信息");
    }

}
